#!/usr/bin/env python3
import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext, filedialog
import subprocess
import os
import json
import threading
import re
import shutil
import locale
from datetime import datetime

# 配置文件路径
CONFIG_FILE = os.path.expanduser("~/.config/arch_cleaner.json")
# 日志文件路径
LOG_FILE = "/var/log/arch_cleaner_pro.log"

# 国际化字符串
STRINGS = {
    "zh_CN.UTF-8": {
        "title": "ArchCleaner Pro 2025",
        "smart_clean": "智能清理",
        "package_cache": "清理包缓存",
        "old_kernels": "删除旧内核",
        "user_cache": "清理用户缓存",
        "large_files": "查找大文件",
        "logs": "清理日志",
        "advanced_tools": "高级工具",
        "custom_path": "自定义清理路径",
        "safe_mode": "安全清理模式",
        "docker": "清理Docker镜像",
        "catos_opt": "CatOS系统优化",
        "mem_clean": "清理内存缓存",
        "vram_clean": "清理显存",
        "kill_process": "进程管理",
        "perf_mode": "性能模式",
        "temp_clean": "清理临时文件",
        "disable_sleep": "禁用休眠",
        "log": "操作日志",
        "status": "状态: 就绪",
        "process_manager": "进程管理器",
        "need_root": "需要管理员权限！",
        "optimization_confirm": "确认执行系统优化操作？",
        "about_content": """ArchCleaner Pro 2025
作者：Silver
功能：Arch系统与CatOS系统优化工具
交流群：428382413""",
        "language_menu": "语言",
        "refresh": "刷新",
        "exit": "退出",
        "file_menu": "文件",
        "help_menu": "帮助"
    },
    "en_US.UTF-8": {
        "title": "ArchCleaner Pro 2025",
        "smart_clean": "Smart Clean",
        "package_cache": "Clean Package Cache",
        "old_kernels": "Remove Old Kernels",
        "user_cache": "Clean User Cache",
        "large_files": "Find Large Files",
        "logs": "Clean Logs",
        "advanced_tools": "Advanced Tools",
        "custom_path": "Custom Clean Path",
        "safe_mode": "Safe Clean Mode",
        "docker": "Clean Docker Images",
        "catos_opt": "CatOS System Optimization",
        "mem_clean": "Clear Memory",
        "vram_clean": "Clean VRAM",
        "kill_process": "Process Manager",
        "perf_mode": "Performance Mode",
        "temp_clean": "Clean Temp Files",
        "disable_sleep": "Disable Sleep",
        "log": "Operation Log",
        "status": "Status: Ready",
        "process_manager": "Process Manager",
        "need_root": "Root privileges required!",
        "optimization_confirm": "Confirm system optimization?",
        "about_content": """ArchCleaner Pro 2025
Author: Silver
Function: Arch & CatOS System Optimization Tool
Group: 428382413""",
        "language_menu": "Language",
        "refresh": "Refresh",
        "exit": "Exit",
        "file_menu": "File",
        "help_menu": "Help"
    }
}

class ArchCleanerPro:
    def __init__(self, root):
        """初始化应用"""
        self.root = root
        self.current_lang = tk.StringVar(value="zh_CN.UTF-8")
        self.config = self.load_config()  # 加载配置
        self.lang = STRINGS[self.current_lang.get()]
        self.setup_language()
        self.setup_ui()  # 设置界面
        self.check_dependencies()  # 检查依赖
        self.check_root()

    def setup_language(self):
        """设置语言环境"""
        lang = self.current_lang.get()
        try:
            locale.setlocale(locale.LC_ALL, lang)
            self.lang = STRINGS[lang]
        except Exception as e:
            self.lang = STRINGS["en_US.UTF-8"]
            self.log(f"语言设置失败: {str(e)}")

    def setup_ui(self):
        """设置主界面布局"""
        self.root.title(self.lang["title"])
        self.root.geometry("1200x800")

        # 设置主题样式
        style = ttk.Style()
        style.theme_use('clam')
        style.configure('TNotebook.Tab', font=('Helvetica', 10, 'bold'))

        # 选项卡容器
        notebook = ttk.Notebook(self.root)
        notebook.pack(fill=tk.BOTH, expand=True)

        # 智能清理
        clean_frame = ttk.Frame(notebook)
        self.build_clean_section(clean_frame)
        notebook.add(clean_frame, text=self.lang["smart_clean"])

        # 高级工具
        advanced_frame = ttk.Frame(notebook)
        self.build_advanced_section(advanced_frame)
        notebook.add(advanced_frame, text=self.lang["advanced_tools"])

        # CatOS系统优化
        catos_frame = ttk.Frame(notebook)
        self.build_catos_section(catos_frame)
        notebook.add(catos_frame, text=self.lang["catos_opt"])

        # 日志系统
        self.log_area = scrolledtext.ScrolledText(self.root, wrap=tk.WORD)
        self.log_area.pack(fill=tk.BOTH, expand=True)
        self.log_area.tag_config('error', foreground='red')
        self.log_area.tag_config('success', foreground='green')

        # 进度条
        self.progress = ttk.Progressbar(self.root, mode='determinate')
        self.progress.pack(fill=tk.X)

        # 创建菜单
        self.create_menu()

        # 状态栏
        self.status_bar = ttk.Label(self.root, text=self.lang["status"])
        self.status_bar.pack(side="bottom", fill="x")

    def create_menu(self):
        """创建菜单系统"""
        menubar = tk.Menu(self.root)
        
        # 文件菜单
        file_menu = tk.Menu(menubar, tearoff=0)
        file_menu.add_command(label=self.lang["refresh"], command=self.reload_ui)
        file_menu.add_separator()
        file_menu.add_command(label=self.lang["exit"], command=self.root.quit)
        menubar.add_cascade(label=self.lang["file_menu"], menu=file_menu)

        # 语言菜单
        lang_menu = tk.Menu(menubar, tearoff=0)
        lang_menu.add_radiobutton(
            label="中文",
            variable=self.current_lang,
            value="zh_CN.UTF-8",
            command=self.reload_ui
        )
        lang_menu.add_radiobutton(
            label="English",
            variable=self.current_lang,
            value="en_US.UTF-8",
            command=self.reload_ui
        )
        menubar.add_cascade(label=self.lang["language_menu"], menu=lang_menu)

        # 帮助菜单
        help_menu = tk.Menu(menubar, tearoff=0)
        help_menu.add_command(label=self.lang["help_menu"], command=self.show_about)
        help_menu.add_command(label="Check Update", command=self.check_update)
        menubar.add_cascade(label=self.lang["help_menu"], menu=help_menu)

        self.root.config(menu=menubar)

    def build_clean_section(self, parent):
        """构建智能清理模块布局"""
        cols = 3
        ttk.Button(parent, text=self.lang["smart_clean"], command=lambda: self.smart_clean()).grid(row=0, column=0, padx=5)
        ttk.Button(parent, text=self.lang["package_cache"], command=lambda: self.clean_package_cache()).grid(row=0, column=1)
        ttk.Button(parent, text=self.lang["old_kernels"], command=lambda: self.clean_old_kernels()).grid(row=0, column=2)
        ttk.Button(parent, text=self.lang["user_cache"], command=lambda: self.clean_user_cache()).grid(row=1, column=0)
        ttk.Button(parent, text=self.lang["large_files"], command=lambda: self.find_large_files()).grid(row=1, column=1)
        ttk.Button(parent, text=self.lang["logs"], command=lambda: self.clean_logs()).grid(row=1, column=2)

    def build_advanced_section(self, parent):
        """构建高级工具模块"""
        ttk.Label(parent, text=self.lang["custom_path"] + ":").grid(row=0, column=0)
        self.custom_path = ttk.Entry(parent, width=40)
        self.custom_path.grid(row=0, column=1)
        ttk.Button(parent, text="浏览...", command=self.select_custom_path).grid(row=0, column=2)
        ttk.Button(parent, text=self.lang["safe_mode"], command=self.safe_clean_mode).grid(row=1, column=0)
        ttk.Button(parent, text=self.lang["docker"], command=self.clean_docker).grid(row=1, column=1)

    def build_catos_section(self, parent):
        """构建CatOS系统优化模块"""
        cols = 3
        ttk.Button(parent, text=self.lang["mem_clean"], command=self.clean_memory).grid(row=0, column=0, padx=5)
        ttk.Button(parent, text=self.lang["vram_clean"], command=self.clean_vram).grid(row=0, column=1)
        ttk.Button(parent, text=self.lang["kill_process"], command=self.show_process_manager).grid(row=0, column=2)
        ttk.Button(parent, text=self.lang["perf_mode"], command=self.set_performance_mode).grid(row=1, column=0)
        ttk.Button(parent, text=self.lang["temp_clean"], command=self.clean_temp_files).grid(row=1, column=1)
        ttk.Button(parent, text=self.lang["disable_sleep"], command=self.disable_sleep).grid(row=1, column=2)
        ttk.Button(parent, text=self.lang["catos_opt"], command=self.catos_optimization).grid(row=2, column=0)

    def select_custom_path(self):
        """打开文件选择对话框，选择自定义路径"""
        path = filedialog.askdirectory()
        if path:
            self.custom_path.delete(0, tk.END)
            self.custom_path.insert(0, path)

    def safe_clean_mode(self):
        """安全清理模式"""
        messagebox.showinfo(self.lang["safe_mode"], "安全清理模式已启动。\n此功能正在开发中，目前不执行任何操作。")

    def clean_docker(self):
        """清理Docker镜像"""
        cmds = [
            "docker system prune -f",
            "docker image prune -a -f"
        ]
        self.run_cmds(cmds)
        self.log("Docker清理完成", 'success')

    def check_root(self):
        """检查root权限"""
        if os.geteuid() != 0:
            messagebox.showwarning(self.lang["title"], self.lang["need_root"])

    # 智能清理模块 --------------------------------------------------
    def smart_clean(self):
        """智能清理流程"""
        tasks = [
            (self.lang["package_cache"], self.clean_package_cache),
            (self.lang["user_cache"], self.clean_user_cache),
            (self.lang["old_kernels"], self.clean_old_kernels),
            (self.lang["logs"], self.clean_logs)
        ]

        def execute_tasks():
            total = len(tasks)
            for idx, (name, task) in enumerate(tasks):
                self.update_progress((idx + 1) / total * 100)
                self.log(f"正在执行: {name}...", 'info')
                try:
                    task()
                except Exception as e:
                    self.log(f"错误: {str(e)}", 'error')
            self.log("智能清理完成!", 'success')

        threading.Thread(target=execute_tasks).start()

    def clean_package_cache(self):
        """优化后的包缓存清理"""
        keep = self.config.get('keep_versions', 2)
        cmds = [
            'pacman -Sc --noconfirm',
            f'paccache -rk{keep}'
        ]
        self.run_cmds(cmds)
        self.log("包缓存清理完成", 'success')

    def clean_old_kernels(self):
        """安全删除旧内核"""
        if not shutil.which('mhwd-kernel'):
            self.log("mhwd-kernel 未安装或不可用", 'error')
            self.show_warning("mhwd-kernel 未安装或不可用，请手动安装或使用其他工具管理内核。")
            return

        current = subprocess.check_output('uname -r', shell=True).decode().strip()
        try:
            kernels = subprocess.check_output('mhwd-kernel -l', shell=True).decode()
        except subprocess.CalledProcessError as e:
            self.log(f"执行失败: mhwd-kernel -l\n{e.output.decode()}", 'error')
            return

        to_remove = []
        for line in kernels.splitlines():
            if 'linux' in line and current not in line:
                match = re.search(r'linux\d+', line)
                if match:
                    to_remove.append(match.group())

        if to_remove:
            self.run_cmds([f'pacman -Rns {" ".join(to_remove)}'])

    def clean_user_cache(self):
        """清理用户级缓存"""
        dirs = [
            '~/.cache/*',
            '~/.thumbnails',
            '~/.local/share/Trash'
        ]
        expanded_dirs = [os.path.expanduser(d) for d in dirs]
        cmds = [f'rm -rf {d}' for d in expanded_dirs]
        self.run_cmds(cmds)
        self.log("用户缓存清理完成", 'success')

    def find_large_files(self):
        """查找大文件"""
        cmd = r"find / -type f -size +100M ! -path '/proc/*' ! -path '/sys/*' ! -path '/run/*' ! -path '/usr/lib/*' -exec ls -lh {} \; 2>/dev/null"
        try:
            result = subprocess.run(
                cmd,
                shell=True,
                check=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT
            )
            self.log(result.stdout.decode(), 'info')
        except subprocess.CalledProcessError as e:
            self.log(f"执行失败: {cmd}\n{e.output.decode()}", 'error')
        self.log("大文件查找完成", 'success')

    def clean_logs(self):
        """清理系统日志"""
        cmds = [
            'journalctl --vacuum-time=7d',
            'rm -rf /var/log/journal/*'
        ]
        self.run_cmds(cmds)
        self.log("系统日志清理完成", 'success')

    # CatOS系统优化模块 --------------------------------------------------
    def clean_memory(self):
        """清理内存缓存"""
        if messagebox.askyesno(self.lang["title"], "确定要清理内存缓存吗？"):
            self.run_command("sync && echo 3 > /proc/sys/vm/drop_caches", need_root=True)
            self.log("内存缓存已清理", 'success')

    def clean_vram(self):
        """清理显存"""
        output = self.run_command("nvidia-smi --query-compute-apps=pid,gpu_name,used_memory --format=csv")
        if output and "No running" not in output:
            self.run_command("nvidia-smi --gpu-reset -i 0", need_root=True)
            self.log("显存已重置", 'success')
        else:
            self.log("未发现显存残留", 'info')

    def show_process_manager(self):
        """进程管理"""
        process_win = tk.Toplevel(self.root)
        process_win.title(self.lang["process_manager"])
        # 进程列表
        processes = subprocess.check_output(
            "ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu",
            shell=True).decode()
        text = scrolledtext.ScrolledText(process_win)
        text.insert("end", processes)
        text.pack(fill="both", expand=True)
        # 进程操作
        pid_frame = ttk.Frame(process_win)
        pid_frame.pack(pady=5)
        ttk.Label(pid_frame, text="PID:").pack(side="left")
        pid_entry = ttk.Entry(pid_frame, width=10)
        pid_entry.pack(side="left", padx=5)
        ttk.Button(pid_frame, text="结束进程", 
                 command=lambda: self.kill_process(pid_entry.get())).pack(side="left")

    def kill_process(self, pid):
        """结束指定进程"""
        if pid and pid.isdigit():
            self.run_command(f"kill -9 {pid}", need_root=True)
            self.log(f"已结束进程 {pid}", 'success')
        else:
            self.log("无效的PID", 'error')

    def set_performance_mode(self):
        """性能模式"""
        self.run_command("echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor", 
                       need_root=True)
        self.log("已启用性能模式", 'success')

    def clean_temp_files(self):
        """清理临时文件"""
        if messagebox.askyesno(self.lang["title"], "确定要清理临时文件吗？"):
            self.run_command("rm -rf /tmp/*", need_root=True)
            self.log("临时文件已清理", 'success')

    def disable_sleep(self):
        """禁用休眠"""
        self.run_command("systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target", 
                       need_root=True)
        self.log("已禁用休眠功能", 'success')

    def catos_optimization(self):
        """系统优化"""
        if messagebox.askyesno(self.lang["title"], self.lang["optimization_confirm"]):
            self.log("开始系统优化...")
            # 这里添加具体优化步骤
            self.log("系统优化完成", 'success')

    # 辅助功能 -----------------------------------------------------
    def run_cmds(self, cmds):
        """执行命令列表"""
        if not shutil.which('pkexec'):
            self.log("pkexec 未安装或不可用", 'error')
            return

        for cmd in cmds:
            try:
                result = subprocess.run(
                    ['pkexec'] + cmd.split(),
                    check=True,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT
                )
                self.log(result.stdout.decode(), 'info')
            except subprocess.CalledProcessError as e:
                self.log(f"执行失败: {cmd}\n{e.output.decode()}", 'error')

    def run_command(self, command, need_root=False):
        """执行系统命令"""
        try:
            if need_root and not self.check_root(show_warning=True):
                return None
            result = subprocess.run(
                command,
                shell=True,
                check=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                encoding="utf-8",
                errors="replace"
            )
            self.log(result.stdout)
            return result.stdout
        except subprocess.CalledProcessError as e:
            error_msg = f"命令执行失败: {e.cmd}\n错误信息: {e.stderr}"
            self.log(error_msg, 'error')
            return None
        except Exception as e:
            self.log(f"未知错误: {str(e)}", 'error')
            return None

    def log(self, message, tag='info'):
        """增强日志系统"""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.log_area.configure(state='normal')
        self.log_area.insert(tk.END, f"[{timestamp}] {message}\n", tag)
        self.log_area.configure(state='disabled')
        self.log_area.see(tk.END)

    def update_progress(self, value):
        """更新进度条"""
        self.progress['value'] = value
        self.root.update_idletasks()

    def show_warning(self, message):
        """显示警告消息"""
        messagebox.showwarning(self.lang["title"], message)

    def reload_ui(self):
        """重新加载界面"""
        self.root.destroy()
        self.__init__(tk.Tk())

    # 配置管理 -----------------------------------------------------
    def load_config(self):
        """加载用户配置"""
        default = {
            'keep_versions': 2,
            'max_log_size': 100,
            'exclude_dirs': ['/home', '/etc']
        }
        os.makedirs(os.path.dirname(CONFIG_FILE), exist_ok=True)
        try:
            with open(CONFIG_FILE) as f:
                return {**default, **json.load(f)}
        except:
            return default

    def save_config(self):
        """保存配置"""
        os.makedirs(os.path.dirname(CONFIG_FILE), exist_ok=True)
        with open(CONFIG_FILE, 'w') as f:
            json.dump(self.config, f)

    # 依赖检查 -----------------------------------------------------
    def check_dependencies(self):
        """检查必要依赖"""
        required = ['pacman-contrib', 'polkit', 'docker', 'mhwd-kernel']
        missing = [pkg for pkg in required if not self.check_installed(pkg)]

        if missing:
            response = messagebox.askyesno(
                "依赖检查",
                f"缺少以下依赖：{', '.join(missing)}\n是否自动安装这些依赖？"
            )
            if response:
                for pkg in missing:
                    if not self.install_package(pkg):
                        messagebox.showerror("安装失败", f"安装 {pkg} 失败，请手动安装。")
                        return
                messagebox.showinfo("安装成功", "所有依赖已成功安装。")
            else:
                messagebox.showwarning("警告", "某些功能可能无法正常使用，因为缺少必要的依赖。")

    def check_installed(self, pkg):
        """检查软件包是否安装"""
        return subprocess.run(
            f"pacman -Qi {pkg}",
            shell=True,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL
        ).returncode == 0

    def install_package(self, pkg):
        """安装软件包"""
        try:
            subprocess.run(
                f"sudo pacman -S --noconfirm {pkg}",
                shell=True,
                check=True
            )
            return True
        except subprocess.CalledProcessError:
            return False

    # 其他功能 -----------------------------------------------------
    def show_about(self):
        """显示关于信息"""
        messagebox.showinfo(self.lang["title"], self.lang["about_content"])

    def check_update(self):
        """检查更新"""
        self.log("正在检查更新...")
        # 这里添加更新检查逻辑
        self.log("当前已是最新版本", 'success')


if __name__ == "__main__":
    root = tk.Tk()
    style = ttk.Style()
    style.configure("TButton", padding=6)
    style.configure("TLabel", font=('Arial', 10))
    app = ArchCleanerPro(root)
    root.mainloop()